package net.huashitong.ssydt.provider.pk.service;


import huashitong.util.date.DateUtils;
import net.huashitong.ssydt.exam.entity.SsExamQuestion;
import net.huashitong.ssydt.exam.entity.vo.BaseQuestion;
import net.huashitong.ssydt.exceptions.ServiceException;
import net.huashitong.ssydt.money.constant.OperationEnum;
import net.huashitong.ssydt.msg.constant.MessageConsts;
import net.huashitong.ssydt.pk.entity.*;
import net.huashitong.ssydt.pk.entity.vo.*;
import net.huashitong.ssydt.provider.exam.service.ExamService;
import net.huashitong.ssydt.provider.exam.service.SsExamQuestionService;
import net.huashitong.ssydt.provider.money.service.SsMoneyGoldService;
import net.huashitong.ssydt.provider.msg.dto.SsSingleMessage;
import net.huashitong.ssydt.provider.msg.service.MsgPushService;
import net.huashitong.ssydt.provider.task.service.SsTaskMedalRecordService;
import net.huashitong.ssydt.provider.task.service.SsTaskMyCardService;
import net.huashitong.ssydt.provider.task.service.SsTaskMyMedalService;
import net.huashitong.ssydt.provider.user.service.UserService;
import net.huashitong.ssydt.provider.vo.BaseLongIdPagingVO;
import net.huashitong.ssydt.task.constant.TaskConsts;
import net.huashitong.ssydt.task.entity.SsTaskMedalRecord;
import net.huashitong.ssydt.task.entity.SsTaskMyCard;
import net.huashitong.ssydt.task.entity.SsTaskMyMedal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author <a href="mailto:yhy23456@163.com">huiyang.yu</a>
 * @since 2017.12.18
 */
@Service
@Transactional
public class YzddServiceImpl implements YzddService {

    private Logger logger = LoggerFactory.getLogger(YzddService.class);

    private SsPkMyChallengeService ssPkMyChallengeService;

    private SsPkYzddMatchRecordService ssPkYzddMatchRecordService;

    private SsPkYzddMyRankService ssPkYzddMyRankService;

    private SsPkYzddChallengeRecordService ssPkYzddChallengeRecordService;

    private SsMoneyGoldService ssMoneyGoldService;

    private SsExamQuestionService ssExamQuestionService;

    private ExamService examService;

    private SsPkYzddQuestionRecordService ssPkYzddQuestionRecordService;

    private SsPkYzddMyMedalService ssPkYzddMyMedalService;

    private SsPkYzddMedalRankService ssPkYzddMedalRankService;

    private UserService userService;

    private SsPkYzddRankService ssPkYzddRankService;

    private MsgPushService msgPushService;

    private SsTaskMedalRecordService ssTaskMedalRecordService;

    private SsTaskMyMedalService ssTaskMyMedalService;

    private SsTaskMyCardService ssTaskMyCardService;

    @Autowired
    public YzddServiceImpl(SsPkMyChallengeService ssPkMyChallengeService,
                           SsPkYzddMatchRecordService ssPkYzddMatchRecordService,
                           SsPkYzddMyRankService ssPkYzddMyRankService,
                           SsPkYzddChallengeRecordService ssPkYzddChallengeRecordService,
                           SsMoneyGoldService ssMoneyGoldService,
                           SsExamQuestionService ssExamQuestionService,
                           ExamService examService,
                           SsPkYzddQuestionRecordService ssPkYzddQuestionRecordService,
                           SsPkYzddMyMedalService ssPkYzddMyMedalService,
                           SsPkYzddMedalRankService ssPkYzddMedalRankService,
                           UserService userService,
                           SsPkYzddRankService ssPkYzddRankService,
                           MsgPushService msgPushService,
                           SsTaskMedalRecordService ssTaskMedalRecordService,
                           SsTaskMyMedalService ssTaskMyMedalService,
                           SsTaskMyCardService ssTaskMyCardService) {
        this.ssPkMyChallengeService = ssPkMyChallengeService;
        this.ssPkYzddMatchRecordService = ssPkYzddMatchRecordService;
        this.ssPkYzddMyRankService = ssPkYzddMyRankService;
        this.ssPkYzddChallengeRecordService = ssPkYzddChallengeRecordService;
        this.ssMoneyGoldService = ssMoneyGoldService;
        this.ssExamQuestionService = ssExamQuestionService;
        this.examService = examService;
        this.ssPkYzddQuestionRecordService = ssPkYzddQuestionRecordService;
        this.ssPkYzddMyMedalService = ssPkYzddMyMedalService;
        this.ssPkYzddMedalRankService = ssPkYzddMedalRankService;
        this.userService = userService;
        this.ssPkYzddRankService = ssPkYzddRankService;
        this.msgPushService = msgPushService;
        this.ssTaskMedalRecordService = ssTaskMedalRecordService;
        this.ssTaskMyMedalService = ssTaskMyMedalService;
        this.ssTaskMyCardService = ssTaskMyCardService;
    }

    @Override
    public GameRuleVO get() {
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        GameRuleVO vo = null;
        if (ssPkYzddMatchRecord == null) {
            vo = new GameRuleVO();
        } else {
            vo = new GameRuleVO(ssPkYzddMatchRecord);
        }
        return vo;
    }

    @Override
    public Integer getFree(String userId) {
        SsPkMyChallenge ssPkMyChallenge = ssPkMyChallengeService.getAutoUpdateByUserId(userId);
        return ssPkMyChallenge.getYzdd();
    }

    @Override
    public int getTimer() {
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        long endTime = DateUtils.parseDate(ssPkYzddMatchRecord.getEndTime()).getTime();
        return (int) ((endTime - System.currentTimeMillis()) / 1000);
    }

    @Override
    public MyRankVO getMyRank(String userId) {
        SsPkYzddMatchRecord matchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        SsPkYzddMyRank myRank = ssPkYzddMyRankService.getAutoUpdateRankByMatchRecordIdWithUserId(matchRecord.getId(), userId);
        return new MyRankVO(myRank);
    }

    @Override
    public void postRemoveError(ChallengePrivilegeVO challengePrivilegeVO, String userId) {
        SsPkYzddChallengeRecord challengeRecord = ssPkYzddChallengeRecordService
                .selectByPrimaryKey(challengePrivilegeVO.getRecordId());
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.selectByPrimaryKey(challengeRecord.getMatchRecordId());
        Integer removeErrorTimes = challengeRecord.getRemoveErrorTimes();
        int times = challengePrivilegeVO.getTimes() - removeErrorTimes;
        while (times > 0) {
            removeErrorTimes++;
            long goldNumber = ssPkYzddMatchRecord.getRemoveErrorGold() * removeErrorTimes;
            ssMoneyGoldService.modifyAndRecordBill(userId, OperationEnum.SUBTRACT, goldNumber, "一站到底去除错误答案");
            times--;
        }
        challengeRecord.setRemoveErrorTimes(removeErrorTimes);
        ssPkYzddChallengeRecordService.updateByPrimaryKey(challengeRecord);
    }

    @Override
    public void postSelectedCorrect(ChallengePrivilegeVO challengePrivilegeVO, String userId) {
        SsPkYzddChallengeRecord challengeRecord = ssPkYzddChallengeRecordService
                .selectByPrimaryKey(challengePrivilegeVO.getRecordId());
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.selectByPrimaryKey(challengeRecord.getMatchRecordId());
        Integer selectedCorrect = challengeRecord.getSelectedCorrectTimes();
        int times = challengePrivilegeVO.getTimes() - selectedCorrect;
        while (times > 0) {
            selectedCorrect++;
            long goldNumber = ssPkYzddMatchRecord.getSelectedCorrectGold() * selectedCorrect;
            ssMoneyGoldService.modifyAndRecordBill(userId, OperationEnum.SUBTRACT, goldNumber, "一站到底选中正确答案");
            times--;
        }
        challengeRecord.setSelectedCorrectTimes(selectedCorrect);
        ssPkYzddChallengeRecordService.updateByPrimaryKey(challengeRecord);
    }

    @Override
    public void postRevive(ChallengePrivilegeVO challengePrivilegeVO, String userId) {
        SsPkYzddChallengeRecord challengeRecord = ssPkYzddChallengeRecordService
                .selectByPrimaryKey(challengePrivilegeVO.getRecordId());
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.selectByPrimaryKey(challengeRecord.getMatchRecordId());
        Integer revive = challengeRecord.getReviveTimes();
        int times = challengePrivilegeVO.getTimes() - revive;
        while (times > 0) {
            revive++;
            long goldNumber = ssPkYzddMatchRecord.getReviveGold() * revive;
            ssMoneyGoldService.modifyAndRecordBill(userId, OperationEnum.SUBTRACT, goldNumber, "一站到底继续刷题");
            times--;
        }
        challengeRecord.setReviveTimes(revive);
        ssPkYzddChallengeRecordService.updateByPrimaryKey(challengeRecord);

    }

    @Override
    public ChallengeRecordVO postChallenge(String userId, YzddChallengeVO yzddChallengeVO) {
        //取题返回（判断是否第一次取题）
        SsPkYzddChallengeRecord record;
        boolean isNew = true;
        if (yzddChallengeVO.getRecordId() != null) {
            record = ssPkYzddChallengeRecordService.selectByPrimaryKey(yzddChallengeVO.getRecordId());
            if (record == null) {
                throw new ServiceException("挑战记录不存在");
            }
            if (yzddChallengeVO.getLoadNumber() == null || yzddChallengeVO.getLoadNumber() <= 1) {
                throw new ServiceException("加载次数错误");
            }
            if (record.getLoadNumber() >= yzddChallengeVO.getLoadNumber()) {
                isNew = false;
            } else {
                record.setLoadNumber(yzddChallengeVO.getLoadNumber());
                ssPkYzddChallengeRecordService.updateByPrimaryKey(record);
            }
        } else {
            //消耗免费次数或扣金币
            consumeTimesOrGold(userId);
            record = saveNewSsPkYzddChallengeRecord(userId);//保存新记录
        }

        List<BaseQuestion> questions;
        if (isNew) {//取新题
            questions = getNewQuestions(record.getId(), yzddChallengeVO.getLoadNumber(), userId);
        } else {//取历史
            questions = getOldQuestions(yzddChallengeVO.getRecordId(),
                    yzddChallengeVO.getLoadNumber(), userId);
        }

        ChallengeRecordVO vo = new ChallengeRecordVO(record);
        vo.setQuestions(questions);
        return vo;

    }

    @Override
    public ChallengeRecordVO postChallengeSubmit(ChallengeSubmitVO challengeSubmitVO, String userId) {
        SsPkYzddChallengeRecord record = ssPkYzddChallengeRecordService
                .selectByPrimaryKey(challengeSubmitVO.getRecordId());
        if (record == null) {
            throw new ServiceException("挑战记录不存在");
        }
        if (record.getIsSubmit().equals((byte) 1)) {
            return new ChallengeRecordVO(record);
        }
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.selectByPrimaryKey(record.getMatchRecordId());
        //统计获得金币数
        long goldNumber = ssPkYzddMatchRecord.getRightAnswerGold() * challengeSubmitVO.getCorrectNumber();

        //计算勋章加成
        SsTaskMyMedal ssTaskMyMedal = ssTaskMyMedalService.getAutoCreateByUserId(record.getUserId());
        //计算卡包加成
        SsTaskMyCard ssTaskMyCard = ssTaskMyCardService.getAutoCreateByUserId(record.getUserId());
        //卷面成绩
        challengeSubmitVO.setPaperScore(challengeSubmitVO.getPaperScore().setScale(3, BigDecimal.ROUND_DOWN));
        //统计总分
        BigDecimal totalScore = challengeSubmitVO.getPaperScore()
                .add(ssTaskMyMedal.getAddScore())
                .add(ssTaskMyCard.getAddScore());

        //统计排名和变动名次
        //排名
        SsPkYzddMyRank ssPkYzddMyRank = ssPkYzddMyRankService
                .getAutoLoadLastRankByMatchRecordIdWithUserId(record.getMatchRecordId(), userId);
        int oldRanking = ssPkYzddMyRank.getRanking();
        if (ssPkYzddMyRank.getHighestScore().compareTo(totalScore) < 0) {
            ssPkYzddMyRank.setHighestScore(totalScore);
            ssPkYzddMyRank.setHighestGmtModified(new Date(System.currentTimeMillis()));
        }
        ssPkYzddMyRank = ssPkYzddMyRankService.updateRank(ssPkYzddMyRank);
        //变动名次
        int riseRank = 0;
        if (oldRanking != 0) {
            riseRank = oldRanking - ssPkYzddMyRank.getRanking();
        }
        //给用户增加金币并记录日志
        if (goldNumber > 0) {
            ssMoneyGoldService.modifyAndRecordBill(userId, OperationEnum.ADD, goldNumber, "一站到底答对题目奖励");
        }

        //保存比赛记录
        record.setIsSubmit((byte) 1);
        record.setMedalScore(ssTaskMyMedal.getAddScore());
        record.setCardScore(ssTaskMyCard.getAddScore());
        record.setTotalScore(totalScore);
        record.setPaperScore(challengeSubmitVO.getPaperScore());
        record.setRank(ssPkYzddMyRank.getRanking());
        record.setRiseRank(riseRank);
        record.setGoldNumber(goldNumber);
        record.setCorrectNumber(challengeSubmitVO.getCorrectNumber());
        ssPkYzddChallengeRecordService.updateByPrimaryKeySelective(record);

        //返回数据
        return new ChallengeRecordVO(record);
    }

    @Override
    @Scheduled(cron = "0 1/3 * * * ?")
    public void executeRanking() {
        SsPkYzddMatchRecord matchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        generateRank(matchRecord.getId());
    }

    @Override
    public MyMedalVO getMyMedal(String userId) {
        int ranking = 0;
        SsPkYzddMyMedal ssPkYzddMyMedal = ssPkYzddMyMedalService.getAutoCreateByUserId(userId);
        SsPkYzddMedalRank ssPkYzddMedalRank = ssPkYzddMedalRankService.getByUserId(userId);
        if (ssPkYzddMedalRank != null) {
            ranking = ssPkYzddMedalRank.getRanking();
        }
        MyMedalVO myMedalVO = new MyMedalVO(ssPkYzddMyMedal);
        myMedalVO.setRanking(ranking);
        return myMedalVO;
    }

    @Override
    public List<MedalVO> getMedalRank(BaseLongIdPagingVO baseLongIdPagingVO) {
        List<MedalVO> list = new ArrayList<>();
        List<SsPkYzddMedalRank> ssPkYzddMedalRanks = ssPkYzddMedalRankService.query(baseLongIdPagingVO);
        for (SsPkYzddMedalRank ssPkYzddMedalRank : ssPkYzddMedalRanks) {
            MedalVO medalVO = new MedalVO(ssPkYzddMedalRank);
            medalVO.setUser(userService.getSimpleUser(ssPkYzddMedalRank.getUserId()));
            list.add(medalVO);
        }
        return list;
    }

    @Override
    public List<RankingVO> getRanking(RankingInVO rankingInVO) {
        SsPkYzddMatchRecord matchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        rankingInVO.setMatchRecordId(matchRecord.getId());
        List<SsPkYzddRank> ssPkYzddRanks = ssPkYzddRankService.query(rankingInVO);
        List<RankingVO> ranks = new ArrayList<>();
        for (SsPkYzddRank pkYzddRank : ssPkYzddRanks) {
            RankingVO rank = new RankingVO();
            rank.setRanking(pkYzddRank.getRanking());
            rank.setScore(pkYzddRank.getScore());
            rank.setId(pkYzddRank.getId());
            rank.setUser(userService.getSimpleUser(pkYzddRank.getUserId()));
            ranks.add(rank);
        }
        return ranks;
    }

    @Override
    @Scheduled(cron = "0 5/20 9,18 1 * ?")
    public void calculateFinalRankAndSettlementNotify() {
        List<SsPkYzddMatchRecord> ssPkYzddMatchRecords = ssPkYzddMatchRecordService.findNonFinal();
        for (SsPkYzddMatchRecord ssPkYzddMatchRecord : ssPkYzddMatchRecords) {
            //生成最终排行
            generateRank(ssPkYzddMatchRecord.getId());
            //用户奖励金币并推送通知
            List<SsPkYzddRank> ssPkYzddRanks = ssPkYzddRankService.findTopTen(ssPkYzddMatchRecord.getId());
            for (SsPkYzddRank ssPkYzddRank : ssPkYzddRanks) {
                Long goldNumber;
                String description = String.format("一站到底挑战获得第%d名", ssPkYzddRank.getRanking());
                SsPkYzddMyMedal ssPkYzddMyMedal;//更新用户的奖牌
                switch (ssPkYzddRank.getRanking()) {
                    case 1:
                        goldNumber = ssPkYzddMatchRecord.getFirstGold();
                        ssPkYzddMyMedal = ssPkYzddMyMedalService.getAutoCreateByUserId(ssPkYzddRank.getUserId());
                        ssPkYzddMyMedal.setGoldMedal(ssPkYzddMyMedal.getGoldMedal() + 1);
                        ssPkYzddMyMedalService.updateByPrimaryKey(ssPkYzddMyMedal);
                        break;
                    case 2:
                        goldNumber = ssPkYzddMatchRecord.getSecondGold();
                        ssPkYzddMyMedal = ssPkYzddMyMedalService.getAutoCreateByUserId(ssPkYzddRank.getUserId());
                        ssPkYzddMyMedal.setSilverMedal(ssPkYzddMyMedal.getSilverMedal() + 1);
                        ssPkYzddMyMedalService.updateByPrimaryKey(ssPkYzddMyMedal);
                        break;
                    case 3:
                        goldNumber = ssPkYzddMatchRecord.getThirdGold();
                        ssPkYzddMyMedal = ssPkYzddMyMedalService.getAutoCreateByUserId(ssPkYzddRank.getUserId());
                        ssPkYzddMyMedal.setBronzeMedal(ssPkYzddMyMedal.getBronzeMedal() + 1);
                        ssPkYzddMyMedalService.updateByPrimaryKey(ssPkYzddMyMedal);
                        break;
                    default:
                        goldNumber = ssPkYzddMatchRecord.getFourthToTenthGold();
                        break;
                }
                ssMoneyGoldService.modifyAndRecordBill(ssPkYzddRank.getUserId(), OperationEnum.ADD, goldNumber, description);

                SsSingleMessage ssSingleMessage = new SsSingleMessage();
                ssSingleMessage.setRecipient(ssPkYzddRank.getUserId());
                ssSingleMessage.setTitle("一站到底");
                ssSingleMessage.setText(String.format("恭喜您%s，奖励%d金币", description, goldNumber));
                ssSingleMessage.setMsgType(MessageConsts.MsgType.SYSTEM);
                ssSingleMessage.setTargetType(MessageConsts.TargetType.GOLD);
                msgPushService.pushSingleMessage(ssSingleMessage);


            }
            //统计挑战人数
            int participantNumber = ssPkYzddChallengeRecordService
                    .countDistinctUserIdByMatchRecordId(ssPkYzddMatchRecord.getId());
            //更新状态
            ssPkYzddMatchRecord.setParticipantNumber(participantNumber);
            ssPkYzddMatchRecord.setIsFinal((byte) 1);
            ssPkYzddMatchRecord.setIsSettlement((byte) 1);
            ssPkYzddMatchRecordService.updateByPrimaryKey(ssPkYzddMatchRecord);
        }
        logger.info("一站到底奖励发放成功，影响{}条比赛记录", ssPkYzddMatchRecords.size());

        //更新奖牌榜
        if (!ssPkYzddMatchRecords.isEmpty()) {
            this.updateMedalRank();
        }
    }

    /**
     * 生成排行榜
     *
     * @param matchRecordId
     */
    private void generateRank(Long matchRecordId) {
        List<SsPkYzddMyRank> ssPkYzddMyRanks =
                ssPkYzddMyRankService.findHighestScoreDescByMatchRecordId(matchRecordId);
        //先删
        int deleteNumber = ssPkYzddRankService.deleteByMatchRecordId(matchRecordId);
        //后写入
        int i = 1;
        List<SsPkYzddRank> ssPkYzddRanks = new ArrayList<>();
        for (SsPkYzddMyRank ssPkYzddMyRank : ssPkYzddMyRanks) {
            SsPkYzddRank rank = new SsPkYzddRank();
            rank.setMatchRecordId(matchRecordId);
            rank.setUserId(ssPkYzddMyRank.getUserId());
            rank.setScore(ssPkYzddMyRank.getHighestScore());
            rank.setRanking(i++);
            ssPkYzddRanks.add(rank);
        }
        int batchInsertNumber = ssPkYzddRankService.batchInsert(ssPkYzddRanks);
        logger.info("一站到底生成排行榜数据，排行榜删除{}条数据,新增{}条数据", deleteNumber, batchInsertNumber);
    }

    @Override
    public void updateMedalRank() {
        List<SsPkYzddMyMedal> ssPkYzddMyMedals = ssPkYzddMyMedalService.findCountMedalRank();
        List<SsPkYzddMedalRank> ranks = new ArrayList<>();
        int i = 1;
        for (SsPkYzddMyMedal ssPkYzddMyMedal : ssPkYzddMyMedals) {
            SsPkYzddMedalRank ssPkYzddMedalRank = new SsPkYzddMedalRank();
            ssPkYzddMedalRank.setUserId(ssPkYzddMyMedal.getUserId());
            ssPkYzddMedalRank.setGoldMedal(ssPkYzddMyMedal.getGoldMedal());
            ssPkYzddMedalRank.setSilverMedal(ssPkYzddMyMedal.getSilverMedal());
            ssPkYzddMedalRank.setBronzeMedal(ssPkYzddMyMedal.getBronzeMedal());
            ssPkYzddMedalRank.setRanking(i++);
            ranks.add(ssPkYzddMedalRank);
        }
        int deleteNumber = ssPkYzddMedalRankService.deleteAll();
        int addNumber = ssPkYzddMedalRankService.batchInsert(ranks);
        logger.info("更新奖牌榜成功，删除{}条记录，新增{}条记录", deleteNumber, addNumber);
    }

    @Override
    @Scheduled(cron = "0 0 * * * ?")
    public void updateUserTaskMedal() {
        //高分勋章
        List<String> userIds = ssPkYzddChallengeRecordService.findGaofenXunZhang(100);
        for (String userId : userIds) {
            SsTaskMedalRecord medalRecord = new SsTaskMedalRecord();
            medalRecord.setMedalId(TaskConsts.Medal.GAOFEN);
            medalRecord.setUserId(userId);
            ssTaskMedalRecordService.saveAndUpdateMyMedal(medalRecord);
        }
        //学霸勋章
        userIds = ssPkYzddMyMedalService.findXuebaXunZhang();
        for (String userId : userIds) {
            SsTaskMedalRecord medalRecord = new SsTaskMedalRecord();
            medalRecord.setMedalId(TaskConsts.Medal.XUEBA);
            medalRecord.setUserId(userId);
            ssTaskMedalRecordService.saveAndUpdateMyMedal(medalRecord);
        }
        //奋斗勋章
        userIds = ssPkYzddChallengeRecordService.findFendouXunZhang(100);
        for (String userId : userIds) {
            SsTaskMedalRecord medalRecord = new SsTaskMedalRecord();
            medalRecord.setMedalId(TaskConsts.Medal.FENDOU);
            medalRecord.setUserId(userId);
            ssTaskMedalRecordService.saveAndUpdateMyMedal(medalRecord);
        }
        logger.info("一站到底用户勋章发放成功");
    }

    /**
     * 取旧题
     *
     * @param recordId
     * @param loadNumber
     * @param userId
     * @return
     */
    private List<BaseQuestion> getOldQuestions(Long recordId, Integer loadNumber, String userId) {
        List<SsPkYzddQuestionRecord> ssPkYzddQuestionRecords = ssPkYzddQuestionRecordService
                .findByRecordIdWithLoadNumberWithUserId(recordId, loadNumber, userId);
        List<BaseQuestion> questions = new ArrayList<>();
        for (SsPkYzddQuestionRecord ssPkYzddQuestionRecord : ssPkYzddQuestionRecords) {
            BaseQuestion question = examService.getBaseQuestion(ssPkYzddQuestionRecord.getQuestionId());
            questions.add(question);
        }
        return questions;
    }

    /**
     * 取新题
     *
     * @param recordId
     * @param loadNumber
     * @param userId
     */
    private List<BaseQuestion> getNewQuestions(Long recordId, Integer loadNumber, String userId) {
        List<SsExamQuestion> ssExamQuestions;
        if (loadNumber != null) {
            List<SsPkYzddQuestionRecord> ssPkYzddQuestionRecords = ssPkYzddQuestionRecordService
                    .findByRecordIdWithUserId(recordId, userId);
            List<Long> ids = new ArrayList<>();
            for (SsPkYzddQuestionRecord ssPkYzddQuestionRecord : ssPkYzddQuestionRecords) {
                ids.add(ssPkYzddQuestionRecord.getQuestionId());
            }
            ssExamQuestions = ssExamQuestionService
                    .queryTenQuestionForLastYearByQuestionIdNotIn(ids);
        } else {
            ssExamQuestions = ssExamQuestionService
                    .queryTenQuestionForLastYear();
            loadNumber = 1;
        }

        //记刷题记录
        List<SsPkYzddQuestionRecord> ssPkYzddQuestionRecords = new ArrayList<>();
        List<BaseQuestion> questions = new ArrayList<>();
        for (SsExamQuestion ssExamQuestion : ssExamQuestions) {
            BaseQuestion question = examService.getBaseQuestion(ssExamQuestion);
            questions.add(question);

            SsPkYzddQuestionRecord record = new SsPkYzddQuestionRecord();
            record.setChallengeRecordId(recordId);
            record.setUserId(userId);
            record.setLoadNumber(loadNumber);
            record.setQuestionId(ssExamQuestion.getId());
            ssPkYzddQuestionRecords.add(record);
        }
        ssPkYzddQuestionRecordService.batchInsert(ssPkYzddQuestionRecords);

        return questions;
    }

    /**
     * 保存新记录
     *
     * @param userId
     * @return
     */
    private SsPkYzddChallengeRecord saveNewSsPkYzddChallengeRecord(String userId) {
        SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
        SsPkYzddChallengeRecord record = new SsPkYzddChallengeRecord();
        record.setMatchRecordId(ssPkYzddMatchRecord.getId());
        record.setUserId(userId);
        record.setRemoveErrorTimes(0);
        record.setSelectedCorrectTimes(0);
        record.setReviveTimes(0);
        record.setLoadNumber(1);
        record.setIsSubmit((byte) 0);
        record.setTotalScore(BigDecimal.ZERO);
        record.setPaperScore(BigDecimal.ZERO);
        record.setMedalScore(BigDecimal.ZERO);
        record.setCardScore(BigDecimal.ZERO);
        record.setRank(0);
        record.setRiseRank(0);
        record.setGoldNumber(0L);
        record.setCorrectNumber(0);
        ssPkYzddChallengeRecordService.insertSelective(record);
        return record;
    }


    /**
     * 消耗免费次数或扣金币
     *
     * @param userId
     */
    private void consumeTimesOrGold(String userId) {
        SsPkMyChallenge ssPkMyChallenge = ssPkMyChallengeService.getAutoUpdateByUserId(userId);
        if (ssPkMyChallenge.getYzdd() > 0) {
            ssPkMyChallenge.setYzdd(ssPkMyChallenge.getYzdd() - 1);
            ssPkMyChallengeService.updateByPrimaryKey(ssPkMyChallenge);
        } else {
            SsPkYzddMatchRecord ssPkYzddMatchRecord = ssPkYzddMatchRecordService.getNowYzddMatch();
            ssMoneyGoldService.modifyAndRecordBill(userId, OperationEnum.SUBTRACT,
                    ssPkYzddMatchRecord.getChallengeGold(), "挑战一站到底");
        }
    }
}
